home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98

Search this book:
 
Previous Table of Contents Next


Allow Unrounded Floating-Point Operations

This option allows Visual Basic to optimize certain floating-point operations. As a side effect, the program may store variables with greater precision than you expect. The program may consider two extremely close values to be different when you think they are the same.

Situations like these, where the program uses too much precision, can be a problem even when this optimization is not enabled. For example, in the following code the variable x starts with the value 0. The value 10 / 17 is added to x 17 times. If you multiply 17 by 10 / 17, you get 10, so the final value for x should be 10. Due to round-off errors, however, the value differs from 10 by roughly 2E-15. This is not exactly 10, so the test x = 10 in the If statement is false. Unfortunately, the Str$ command does not represent x with enough precision for you to see that x is not 10. The message box displays the rather confusing string, “The value is not 10, it is 10.”

Private Sub RoundoffProblem()
Dim x As Double
Dim dx As Double
Dim i As Integer

    dx = 10 / 17
    x = 0
    For i = 1 To 17
    ‘ Do something with x.
         :
      x = x + dx
    Next i

    If x = 10 Then
       MsgBox “The value is 10.”
    Else
       MsgBox “The value is not 10, it is” & _
       Str$(x) & “.”
       End If
End Sub

If you examine the value of x using the Format$ function, or if you display it in the Immediate window using the Debug.Print command, you receive a similarly confusing result. As far as you can tell, x is 10; yet x = 10 is false.

The way to solve this problem is to not use equality to determine whether floating-point numbers are equal. Instead, see if they differ by some very small amount as in this code:

If Abs(x - 10) < 0.00001 Then

If you use this technique to avoid problems with floating-point numbers stored at very high precision, you can allow unrounded floating-point operations.

Remove Safe Pentium FDIV Checks

If you select this option, the program may produce incorrect results on computers with the infamous Pentium FDIV bug. Use this option only if you are certain you will not perform any floating-point calculations that will cause the bug or if you are sure you will never run the program on a Pentium that has this bug.


Figure 11.2  Program Bad11 is not safe for all optimizations.

Self-Test

Program Bad11, shown in Figure 11.2, performs operations that make some of Visual Basic’s optimizations unsafe. The program is a crude array manager. Enter an array index in the Index box. Enter a floating-point value in the Value box and click the Set button to save the value in the indicated array position. Click the Get button to see what value is currently in that array position.

Examine the code that follows and try to determine why it makes the optimizations unsafe. Appendix A, “Self-Test Solutions,” contains an improved version of the code.

Option Explicit

Private Values(1 To 100) As Single

Private Sub cmdGet_Click()
Dim index As Integer

    On Error GoTo GetError
    index = CLng(txtIndex.Text)
    txtValue.Text = Format$(CellValue(index))
    Exit Sub

GetError:
    MsgBox “Error” & Str$(Err.Number) & _
     “ getting value.” & vbCrLf & _
     Err.Description
End Sub

Private Sub cmdSet_Click()
    On Error GoTo SetError
    CellValue(txtIndex.Text) = txtValue.Text
    Exit Sub

SetError:
    MsgBox “Error” & Str$(Err.Number) & _
     “ setting value.” & vbCrLf & _
     Err.Description
End Sub

‘ Return the indicated array cell value.
Public Property Get CellValue(ByVal index As Integer) As Single
    CellValue = Values(index)
End Property

‘ Set the indicated array cell value.
Public Property Let CellValue(ByVal index As Integer, _
    new_value As Single)

    Values(index) = new_value
End Property

Summary

Probably the biggest optimization mistake developers make is optimizing too soon. Wait until most of the program’s features have been correctly implemented before you begin optimization. Then profile the code and work with a plan instead of trying to improve randomly selected sections of code. The following Bug Stoppers summarize these and the other optimization guidelines discussed in this chapter.

BUG STOPPERS: optimization
Optimize algorithms, not lines of code.
Defer optimization until the program runs correctly.
Profile the program before you optimize.
Use comments to explain optimizations.
Do not worry about slow debugging code.
Understand Visual Basic’s optimizations.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.